V						?= 0
ifeq ($(V),0)
Q						:= @
else
Q						:=
endif

ARCH					?=

ifneq ($(ARCH),)
TOOLCHAIN_FILE			?= toolchain.$(ARCH).cmake
OUTDIR					:= build/$(ARCH)
else
TOOLCHAIN_FILE			?=
OUTDIR					:= build/host
endif

# Disable the built-in implicit rules and built-in variable settings.
# add -rR would cause buildroot fail, so unexport
MAKEFLAGS				+= -rR
# unexport MAKEFLAGS

PWD := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))

MAKE_THIS				:= $(MAKE) --no-print-directory -f Makefile

_CMAKE_LIST				:= $(subst $(PWD)/,,$(shell find $(PWD) -mindepth 2 -type f -name CMakeLists.txt))
CMAKE_LIST				:= $(subst CMakeLists.txt,,$(_CMAKE_LIST)) $(subst /CMakeLists.txt,,$(_CMAKE_LIST))
clean-CMAKE_LIST		:= $(addprefix clean-,$(CMAKE_LIST))
install-CMAKE_LIST		:= $(addprefix install-,$(CMAKE_LIST))

__PHONY += __all
__all: all

PHONY += prepare
prepare:
	@mkdir -p $(OUTDIR)
	$(Q)cmake -S $(PWD) -B $(OUTDIR) \
		-DCMAKE_TOOLCHAIN_FILE=$(TOOLCHAIN_FILE) \
		-DCMAKE_INSTALL_PREFIX=$(OUTDIR)/install \
		-DCMAKE_MAKE_PROGRAM=/usr/bin/make \
		-DCMAKE_BUILD_TYPE=Release \
		-DCMAKE_EXPORT_COMPILE_COMMANDS=ON

$(OUTDIR)/Makefile:
	$(Q)$(MAKE_THIS) prepare

PHONY += all
all: $(OUTDIR)/Makefile
	$(Q)cmake --build $(OUTDIR) -j $(shell nproc)

PHONY += install
install: $(OUTDIR)/Makefile
	$(Q)$(MAKE) -C $(OUTDIR) install

PHONY += clean
clean:
	$(Q)rm -fr $(OUTDIR)

PHONY += subdir clean-subdir install-subdir
__PHONY += $(CMAKE_LIST)
$(CMAKE_LIST): $(OUTDIR)/Makefile
	$(Q)cmake --build $(OUTDIR)/$@ -j $(shell nproc)

__PHONY += $(install-CMAKE_LIST)
$(install-CMAKE_LIST): $(OUTDIR)/Makefile
	$(Q)cmake --build $(OUTDIR)/$(subst install-,,$@) -j $(shell nproc) -- install

__PHONY += $(clean-CMAKE_LIST)
$(clean-CMAKE_LIST):
	$(Q)cmake --build $(OUTDIR)/$(subst clean-,,$@) -j $(shell nproc) -- clean

PHONY += test ctest
test:
	$(Q)$(MAKE) -C $(OUTDIR) test

ctest:
	$(Q)cd $(OUTDIR) && ctest -VV --output-on-failure --stop-on-failure

PHONY += help
help:
	@for t in $(PHONY); do \
		echo "    "$$t; \
	done

.PHONY: $(__PHONY) $(PHONY)
